/* boris*/
#include "libBigNum.h"

big_number big_number::operator *(const big_number &param) const
{
   big_number temp;
   temp=MULTI(*this,param); 
   if(this->_sign==param._sign)       
	  { 
		 temp._sign=true;  ///signed positive
		  return temp;	   
      }//end if
  
    else
	  {
	     temp._sign=false;  ///signed negative
	     return temp;	   
      }//end else
  }
        
big_number big_number::MULTI(const big_number &x,const big_number &y)const
{
	  big_number temp;
	  unsigned long *help_arr, *help_arr1;
	  unsigned long num_a;
	  unsigned long long temp_a,carry=0;
      int flag_frac=1,flag_int=1,int_flag=1,frac_flag=1,i,j,flag=1;
	  unsigned short k,frac=1,size=0,temp_arr_size,temp_frac_size;
	  temp._arr_size=temp_arr_size=x._arr_size+y._arr_size;
	  temp._fractionalPart= temp_frac_size=x._fractionalPart+y._fractionalPart;
	  size=temp._arr_size;

	  help_arr=(unsigned long*) malloc( temp._arr_size*sizeof(unsigned long));  
	  if ( help_arr == NULL)
		throw exception(); //TODO def execption can't allocate memory

	  temp_arr_size--;
	  k=temp_arr_size;
	  for(i=0;i<=temp_arr_size;i++)
		  help_arr[i]=0;
	  for(i=x._arr_size-1;i>=0;i--)
	  { 
		  for(j=y._arr_size-1;j>=0;j--,k--)
			 {
				temp_a=(unsigned long long)y._num_array[j]*(unsigned long long)x._num_array[i];
				   num_a=help_arr[k];
				   help_arr[k]= (help_arr[k]+(unsigned long)(temp_a%1000000000)+carry)%1000000000; //10^9				
				  carry=(num_a+temp_a%1000000000)/1000000000;
				  num_a=help_arr[k-1];
		          help_arr[k-1]=(num_a+temp_a/1000000000+carry)%1000000000;  //10^9
			      carry=(num_a+temp_a/1000000000+carry)/1000000000;
			 }
 		
		  k=--temp_arr_size;		  
	   }
	  for(i=0;i<temp._arr_size-temp._fractionalPart-1;i++)
	     {
	       if(help_arr[i]==0 && flag_int==1)
			   size--;
		   else flag_int=0;	  
	     }
	  for(i=temp._arr_size-1;i>temp._arr_size-temp._fractionalPart;i--)
		  {
	       if(help_arr[i]==0 && flag_frac==1)
		           size--;
		   else
			   {
				   flag_frac=0;
				   frac++;
		       }
	       }
    
	  help_arr1=(unsigned long*) malloc( size*sizeof(unsigned long));
	       if ( help_arr == NULL)
				throw exception(); //TODO def execption can't allocate memory
    flag_int=1;
	for(i=0,k=0;i<=temp._arr_size-temp._fractionalPart-2;i++)
	     {
	       if(!(help_arr[i]==0 && flag_int==1))
		    {
		      help_arr1[k++] = help_arr[i];
			  flag_int=0;
		    }	   
	     }
	help_arr1[k] = help_arr[i];

	flag_frac=1;
	for(i=temp._arr_size-1,k=size-1;i>temp._arr_size-temp._fractionalPart;i--)
	     {
	       if(!(help_arr[i]==0 && flag_frac==1))
		    {
		      help_arr1[k--] = help_arr[i];
			  flag_frac=0;
		    }	   
	     }

	help_arr1[k] = help_arr[i];
	free(temp._num_array);
	temp._num_array = (unsigned long*) malloc(size*sizeof(unsigned long));		
		   if ( temp._num_array == NULL)
		     throw exception(); //TODO def execption can't allocate memory
	memcpy(temp._num_array, help_arr1, size*sizeof(unsigned long));
	temp._arr_size=size;
	temp._fractionalPart=frac;
	free(help_arr);
	free(help_arr1);	
    return temp;
   }


	